#include "com_arcvideo_system_sdk_PicTranscoder.h"
#include "pictranscoderapi.h"
#include "jni_util.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_8) != JNI_OK) {
        return JNI_EVERSION;
    }

    int code = PicTransCoderApi::GetInstance()->Init();
    if (code != 0) {
        printf("Failed initialize PicTranscode library, error code=%d\n", code);
        return JNI_ERR;
    }

    JNIHandle::GetInstance()->Init(env);

    return JNI_VERSION_1_8;
}

/*
 * Class:     com_arcvideo_system_sdk_PicTranscoder
 * Method:    open
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_com_arcvideo_system_sdk_PicTranscoder_open
        (JNIEnv *env, jobject tc) {
    PicTransParam param;
    JNIHandle *h = JNIHandle::GetInstance();

    auto inputPath = env->GetIntField(tc, h->fid_picTranscoder_maxParallelNum);
    param.threadCount = inputPath;
    void *ctx = PicTransCoderApi::GetInstance()->TranscoderOpen(&param);
    return (jlong) (ctx);
}

/*
 * Class:     com_arcvideo_system_sdk_PicTranscoder
 * Method:    put
 * Signature: (Lcom/arcvideo/system/sdk/Task;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_arcvideo_system_sdk_PicTranscoder_put
        (JNIEnv *env, jobject tc, jobject task) {
    // 获取JNIHandle实例
    JNIHandle *h = JNIHandle::GetInstance();

    // 获取PicTranscoder对象的ctx字段值
    jlong ctx = env->GetLongField(tc, h->fid_picTranscoder_ctx);

    // 创建TaskParam对象来存储任务参数
    TaskParam taskParam;

    // 获取并处理输入路径字段，避免重复操作
    auto inputPath = (jstring) env->GetObjectField(task, h->fid_task_inputPath);
    if (inputPath == nullptr) {
        return JNI_FALSE; // 如果输入路径为空，返回JNI_FALSE
    }
    const char *pInputPath = env->GetStringUTFChars(inputPath, JNI_FALSE);
    taskParam.pInputFile = const_cast<char *>(pInputPath);

    // 获取并处理输出路径字段
    auto outPath = (jstring) env->GetObjectField(task, h->fid_task_outPath);
    if (outPath == nullptr) {
        return JNI_FALSE;
    }
    const char *pOutPath = env->GetStringUTFChars(outPath, JNI_FALSE);
    taskParam.pOutputFile = const_cast<char *>(pOutPath);

    // 获取并处理缩略图路径字段（如果有的话）
    auto thumbnailPath = (jstring) env->GetObjectField(task, h->fid_task_thumbnailPath);
    const char *pThumbnailPath = nullptr;
    if (thumbnailPath != nullptr) {
        pThumbnailPath = env->GetStringUTFChars(thumbnailPath, JNI_FALSE);
    }
    taskParam.pThumbNailFile = const_cast<char *>(pThumbnailPath);

    // 获取缩略图宽度
    jint thumbnailWidth = env->GetIntField(task, h->fid_task_thumbnailWidth);
    taskParam.ThumbNailWidth = thumbnailWidth;

    // 获取任务的配置文件（profile）
    jint profile = env->GetIntField(task, h->fid_task_profile);
    taskParam.nProfile = profile;

    // 获取任务的质量设置
    jint quality = env->GetIntField(task, h->fid_task_quality);
    taskParam.nQuailty = quality;

    // 获取同步标志（是否同步执行任务）
    jboolean isSync = env->GetBooleanField(task, h->fid_task_isSync);
    taskParam.bSync = (isSync == JNI_TRUE ? 1 : 0);

    // 调用转换任务的函数，执行任务处理
    int code = PicTransCoderApi::GetInstance()->TranscoderPutTask(reinterpret_cast<void *>(ctx), &taskParam);

    // 释放字符串资源，避免内存泄漏
    env->ReleaseStringUTFChars(inputPath, pInputPath);
    env->ReleaseStringUTFChars(outPath, pOutPath);
    if (thumbnailPath != nullptr) {
        env->ReleaseStringUTFChars(thumbnailPath, pThumbnailPath);
    }

    return (code == 0) ? JNI_TRUE : JNI_FALSE;
}

/*
 * Class:     com_arcvideo_system_sdk_PicTranscoder
 * Method:    waitTaskFinish
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_arcvideo_system_sdk_PicTranscoder_waitTaskFinish
        (JNIEnv *env, jobject tc) {
    JNIHandle *h = JNIHandle::GetInstance();
    jlong ctx = env->GetLongField(tc, h->fid_picTranscoder_ctx);
    int code = PicTransCoderApi::GetInstance()->TranscoderWaitTaskFinish((void *) (ctx));
    return code == 0 ? JNI_TRUE : JNI_FALSE;
}

/*
 * Class:     com_arcvideo_system_sdk_PicTranscoder
 * Method:    close
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_arcvideo_system_sdk_PicTranscoder_close
        (JNIEnv *env, jobject tc) {
    JNIHandle *h = JNIHandle::GetInstance();
    jlong ctx = env->GetLongField(tc, h->fid_picTranscoder_ctx);
    int code = PicTransCoderApi::GetInstance()->TranscoderClose((void *) (ctx));
    return code == 0 ? JNI_TRUE : JNI_FALSE;
}
